
#include "Assignment02.h"
#include "maze.h"
#include "random.h"
#include "grid.h"
#include <iostream>
#include "queue.h"
#include "stack.h"
#include "set.h"
/*
 * Project: 160bAssignment02
 * Created by CS106 C++ Assignment Wizard 0.1
 *
 * Name: [TODO: enter name here]
 * Section: [TODO: enter section leader here]
 * [TODO: Describe assignment]
 */

int main ()
{
	int initX,intiY;
	struct pointT point,nextP;
	Grid<bool> grid(20,20);
	int counter =0;
	
	Maze *mazePtr = new Maze(20,20,true);
	mazePtr->draw();
	
	for(int r =0; r < grid.numRows();r++)
		for(int c=0; c <grid.numCols(); c++) 
			grid(r,c)=false;

	Randomize();
	point.row = RandomInteger(0,mazePtr->numRows()-1);
	point.col = RandomInteger(0,mazePtr->numCols()-1);
	mazePtr->drawMark(point,"Red");
	grid(point.row,point.col)=true;

	nextP.row =point.row;
	nextP.col =point.col;
	while( counter <mazePtr->numRows()*mazePtr->numCols()-1)//how many walls have to knock off? Guess is r*c-1, prove?
	//while (counter < 20)
	//while(true)
	{
		//wrong logic: keep seeking neighour such that it is inhound and is not included
		//while( !(mazePtr->pointInBounds(nextP) && grid(nextP.row,nextP.col)==false) )
				
		switch( RandomInteger(0,3))
			{
				case 0://north
					nextP.row = point.row +1;break; 
				case 1://east
					nextP.col = point.col +1;break;
				case 2://south
					nextP.row = point.row -1;break;
				case 3://west
					nextP.col = point.col -1;break;
			}			
		while( !mazePtr->pointInBounds(nextP) )
		{
			nextP.row =point.row;
			nextP.col =point.col;
			switch( RandomInteger(0,3))
			{
				case 0://north
					nextP.row = point.row +1;break; 
				case 1://east
					nextP.col = point.col +1;break;
				case 2://south
					nextP.row = point.row -1;break;
				case 3://west
					nextP.col = point.col -1;break;
			}
		}
		//cout <<nextP.row <<" "<<nextP.col << "    "<<point.row << " "<<point.col <<endl;
		if(grid(nextP.row,nextP.col)==false)
		{	mazePtr->setWall(nextP,point,false);
			grid(nextP.row,nextP.col)=true;
			counter++;
		}
		//neighbour becomes current point
		point.col = nextP.col;//what happens if point = nextP?? i guess 
		point.row = nextP.row;
	}
    //sovle the maze:
	Stack<struct pointT> pathSoFar,pathS;
	Queue<Stack<struct pointT>> pathsQ;
	Set<struct pointT> pointsSoFar(cmpPoint);
	struct pointT root;

	root.col=0;root.row=0;
	pointsSoFar.add(root); //collections of all the points visited so far
	pathS.push(root); //first point into the path
	pathsQ.enqueue(pathS);//first path into the paths
	while(!pathsQ.isEmpty())
	{
		struct pointT point,tempP,southP,northP,westP,eastP;
		pathS = pathsQ.dequeue();
		point = pathS.peek();
		if(point.row==mazePtr->numRows()-1 && point.col==mazePtr->numCols()-1)
		{
			//solution found
			
	//cout << "path found" <<point.row <<"  "<<point.col<<endl;
			//drawPath()
			while(!pathS.isEmpty())		mazePtr->drawMark(pathS.pop(),"Red");
			break;	
		}

		int valueR=-1,valueC=-1;
		for(int r =0;r<2;r++)
		{
			//valueR =(valueR==1) ?0:1;
			//tempP.row=point.row+valueR;
			for(int c =0; c<2;c++)
			{
				if(r==0){ //row is fixed
					tempP.row = point.row;
					tempP.col =point.col+valueC;
					valueC=(valueC==-1)?1:-1;
				}else
				{	
					valueC=0;
					valueR=(valueR==1)?-1:1;
					tempP.col = point.col;
					tempP.row =point.row+valueR;
				}
	
				if(!pointsSoFar.contains(tempP)  && mazePtr->pointInBounds(tempP)&& !mazePtr->isWall(point,tempP)  )
				{
					Stack <struct pointT> newPath;
					pointsSoFar.add(tempP);
					newPath = pathS;
					newPath.push(tempP);
					pathsQ.enqueue(newPath);
	//	cout <<"path added" <<endl;
				}
//		cout << valueR <<" "<<valueC <<endl;
			}
		}




	}



	return 0;
}

int cmpPoint(struct pointT p1,struct pointT p2)
{
	
	if((p1.row==p2.row) && (p1.col == p2.col)) return 0;
	else if(p1.row <=p2.row &&p1.col <=p2.col) return -1;
	return 1;
	

}
